import { HmacMD5 } from "crypto-js";
import { ErrCode } from "./ErrCode";

export class Tools{
    static _instance:Tools;
    static get instance():Tools{
        if(!this._instance){
            this._instance = new Tools();
        }
        return this._instance;
    }

    dayzero(times){
        let day = new Date(times*1000);
        day.setHours(0,0,0,0);
        return parseInt((day.getTime()/1000).toString());
    }
    Random(min,max){
        return Math.floor(Math.random()*(max-min+1)+min);
    }
    private static Dateformat = function(date:Date,fmt){
        var o = {
            "M+" : date.getMonth()+1, //月份
            "d+" : date.getDate(), //日
            "h+" : date.getHours(),//%24 == 0 ? 0 : date.getHours()%24, //小时
            "H+" : date.getHours(), //小时
            "m+" : date.getMinutes(), //分
            "s+" : date.getSeconds(), //秒
            "q+" : Math.floor((date.getMonth()+3)/3), //季度
            "S" : date.getMilliseconds() //毫秒
            };
            var week = {
            "0" : "/u65e5",
            "1" : "/u4e00",
            "2" : "/u4e8c",
            "3" : "/u4e09",
            "4" : "/u56db",
            "5" : "/u4e94",
            "6" : "/u516d"
            };
            if(/(y+)/.test(fmt)){
            fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
            }
            if(/(E+)/.test(fmt)){
            fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "/u661f/u671f" : "/u5468") : "")+week[date.getDay()+""]);
            }
            for(var k in o){
            if(new RegExp("("+ k +")").test(fmt)){
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
            }
            }
            return fmt;
    }
    /**
     * 
     * @param times 时间戳（秒）
     * @param format 格式化字符串：yy-MM-dd hh:mm:ss
     * @returns 
     */
    public static formattime(times,format:String){
        let date = new Date();
        date.setTime(times*1000);
        return this.Dateformat(date,format);
    }
    /**
     * 将时间戳转换成数字
     * @param time 单位：秒
     */
    public static timestampToNumber(time?:number){
        let date = new Date();
        if(time){
            date.setTime(time*1000);
        }
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();
        const hour = date.getHours();
        const minute = date.getMinutes();
        const second = date.getSeconds();
        const ms = date.getMilliseconds();
        return [year,month,day].map(this.formatNumber).join('')+ ""+[hour,minute,second,ms].map(this.formatNumber).join('');
    }
    private static formatNumber = n => {
        n = n.toString()
        return n[1] ? n : '0' + n
    }
    public static DateToTimestamp(dateStr:string){
        let date = new Date(dateStr);
        return parseInt((date.getTime()/1000).toFixed(0));
    }
    public static get timestamp(){
        return parseInt(new Date().getTime()/1000+'');
    }
    public static md5(value):string{
        return HmacMD5(value,'1234567890abcdefghijklmnopqrstuvwxyz').toString();
    }
    //生成随机字符串
    public static generate(length:number = 32){
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        let noceStr = '', maxPos = chars.length;
        while (length--) noceStr += chars[Math.random() * maxPos | 0];
        return noceStr;
    }
        /**将金额 按分的整数处理 
     * @param {int} price 需要处理的价格
     * @param {boolean} rounded 是否四舍五入(默认:否 不进行四舍五入)
     * @param {int} scaling 缩放值(是否需要将原值进行放大或缩小).默认：100(将原值放大100倍)  
     * @param {int} decimal 是否保留小数点。默认：0 不保留小数点
     *     */
    public static formatMoney(price:number,rounded:boolean = false,scaling:number = 100,decimal:number = 0):number{
        // price = parseFloat(price.toString());
        price = price * scaling;
        return parseFloat((rounded == true?parseFloat(price+'').toFixed(decimal):parseInt(price+''))+'');
    }
    public static formatData(origin:any):any{
      return this.clone(origin);
    }
    /**生成数字id */
    public static makeNumberId(len:number):string{
        if(len < 17){
            // Logs.error("len 长度不能小于17位数");
            return;
        }
        let id = Tools.timestampToNumber().toString();
        while (id.length < len) {
            id += Tools.instance.Random(0,9);
        }
        return id;
    }
    /**全随机数 */
    public static makeRandomNum(len):string{
        let num = "";
        while(num.length < len){
            if(num == ""){
                num += Tools.instance.Random(1,9);
            }else{
                num += Tools.instance.Random(0,9);
            }
        }
        return num;
    }
        
    /**
     * 深拷贝一个对象
     * clone an object
     */
    public static clone(origin):any {
        if (!origin) {
            return;
        }
        if(typeof(origin) == 'string' || typeof(origin) == 'number'){
            return origin;
        }
        let obj = Array.isArray(origin) == true?[]:{};
        for (let f in origin) {
            if (origin.hasOwnProperty(f)) {
                if(typeof(origin[f]) === 'object' && origin[f] != null && origin[f] != undefined){
                    obj[f] = this.clone(origin[f]);
                }else{
                    let v = origin[f];
                    if(v === 'undefined' || v === null || v === 'null' || v === undefined){
                        v = "";
                    }
                    let isnum = parseFloat(v);
                    if(!isNaN(isnum) && isFinite(v)){
                        obj[f] = isnum;
                    }else{
                        obj[f] = v;
                    }
                }
            }
        }
        return obj;
    };

    public static async timeoutAsync(time):Promise<any>{
        return new Promise((resovle,reject)=>{
            setTimeout(() => {
                resovle(ErrCode.SYSTEM_SUCCESS);
            }, time);
        });
    }
}